home *** CD-ROM | disk | FTP | other *** search
/ Windows 95 API Bible / Windows 95 API Bible 3 Disc Set.iso / Win32 API Bible Book 1 of 3.iso / chapte18 / ex6.c < prev    next >
C/C++ Source or Header  |  1994-12-26  |  11KB  |  317 lines

  1. /* snapw32.c - program to capture screen display to clipboard */
  2.  
  3. #include <windows.h>
  4. #include <snapw32.h>
  5.  
  6. // prototype for main entry point.
  7.  
  8. int PASCAL WinMain( HANDLE hInstance, HANDLE hPrevInstance, 
  9.                     LPSTR lpCmdLine, int nCmdShow );
  10.  
  11. // prototype for windows message handler for class "ATOM"
  12.  
  13. LRESULT CALLBACK WndProc( HANDLE, UINT, WPARAM, LPARAM );
  14. LRESULT CALLBACK GrabProc( HANDLE, UINT, WPARAM, LPARAM );
  15.  
  16. // outline block subroutine
  17.  
  18. void OutlineBlock (HWND hWnd, POINTS beg, POINTS end);
  19.  
  20. // instance data
  21.  
  22. HWND     hMainWnd = 0;          // handle of main window
  23. HWND     hGrabWnd = 0;          // window used to grab screen
  24. HANDLE   hInst = 0;             // handle of program instance
  25. char     szBuffer[256];         // work area for print formatting
  26.  
  27.  
  28. int PASCAL WinMain( HANDLE hInstance,        // this instance
  29.                     HANDLE hPrevInstance,    // always 0 in win32
  30.                     LPSTR lpCmdLine,         // command line arguments
  31.                     int nCmdShow )           // always SW_SHOWDEFAULT in win32
  32. {
  33.  
  34.    WNDCLASS  wc;              // buffer to pass when registering class
  35.    MSG msg;                   // buffer to store windows messages
  36.  
  37.    hInst = hInstance;         // store instance in instance data.
  38.  
  39.    // Fill out Class Data for User-Interface Window.
  40.  
  41.    wc.style =(WORD)NULL;
  42.    wc.cbClsExtra = 0;
  43.    wc.cbWndExtra = 0;
  44.    wc.hInstance = hInstance;
  45.    wc.hCursor = (HCURSOR) LoadCursor( (HANDLE)NULL, IDC_ARROW );
  46.    wc.hbrBackground = GetStockObject( WHITE_BRUSH );
  47.    wc.lpszMenuName  =  "SNAPW32";
  48.    wc.lpfnWndProc   = WndProc;
  49.    wc.lpszClassName = "SNAPW32";
  50.  
  51.    if (RegisterClass( &wc ) == 0)
  52.       return FALSE;
  53.  
  54.    // Fill out Class Data for invisible window that is used to capture image. 
  55.  
  56.    wc.style =(WORD)NULL;
  57.    wc.cbClsExtra = 0;
  58.    wc.cbWndExtra = 0;
  59.    wc.hInstance = hInstance;
  60.    wc.hCursor = NULL;
  61.    wc.hbrBackground = GetStockObject( NULL_BRUSH );
  62.    wc.lpszMenuName =  NULL;
  63.    wc.lpfnWndProc = GrabProc;
  64.    wc.lpszClassName = "GRAB";
  65.  
  66.    if (RegisterClass( &wc ) == 0)
  67.       return FALSE;
  68.  
  69.    hMainWnd = CreateWindow( "SNAPW32",
  70.                             "SNAP!",
  71.                             WS_OVERLAPPEDWINDOW,
  72.                             CW_USEDEFAULT, CW_USEDEFAULT,
  73.                             CW_USEDEFAULT, CW_USEDEFAULT,
  74.                             NULL,     // no parent
  75.                             NULL,          // use class menu
  76.                             hInstance,
  77.                             NULL );
  78.  
  79.    if(!hMainWnd)
  80.        return( FALSE );
  81.  
  82.    ShowWindow( hMainWnd, nCmdShow );
  83.  
  84.    UpdateWindow( hMainWnd );
  85.  
  86.    hGrabWnd = CreateWindow( "GRAB",
  87.                             "",
  88.                             WS_POPUP,
  89.                             0, 
  90.                             - GetSystemMetrics(SM_CYCAPTION), // above screen.
  91.                             GetSystemMetrics(SM_CXSCREEN),    // size of screen
  92.                             GetSystemMetrics(SM_CYSCREEN),
  93.                             NULL,          // no parent
  94.                             NULL,          // no menu
  95.                             hInstance,
  96.                             NULL );
  97.  
  98.    if(!hGrabWnd)
  99.        return(FALSE);
  100.  
  101.    // don't show grab window yet.
  102.  
  103.    while( GetMessage( &msg, NULL, 0, 0 ) ) {
  104.         TranslateMessage( &msg );
  105.         DispatchMessage( &msg );
  106.    }
  107.  
  108. }
  109.  
  110. // grabbing global data shared between grab window and snapw32.
  111.  
  112. static BOOL     bCapturing = FALSE;
  113. static BOOL     bBlocking = FALSE;
  114. static POINTS   beg, end, oldend;
  115. static short    xSize, ySize;
  116.  
  117.  
  118. //
  119. //  This is the window message procedure for the user-interface window.
  120. // This is the window that responds to menu requests and invokes the
  121. // screen capture window, "GRAB".
  122. //
  123.  
  124.  
  125. LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  126. {
  127.  
  128.    switch (uMsg)   /* process Windows messages */
  129.    {
  130.        case WM_COMMAND:    /* one of the menu items */
  131.                switch (wParam)
  132.                {
  133.                   case IDM_START:       /* the start capture item */
  134.                      bCapturing = TRUE;
  135.                      bBlocking = FALSE;
  136.                      ShowWindow( hWnd, SW_HIDE );
  137.                      // need to let screen recover here
  138.                      Sleep( 0 );
  139.                      ShowWindow( hGrabWnd, SW_SHOWNORMAL );
  140.                      SetCapture( hGrabWnd );      /* grab mouse */
  141.                      break;
  142.                   case IDM_CLEAR:       /* clears screen and clipboard */
  143.                      OpenClipboard( hWnd );
  144.                      EmptyClipboard( );
  145.                      CloseClipboard( );
  146.                      InvalidateRect( hWnd, NULL, TRUE );
  147.                      break ;
  148.                   case IDM_EXIT:
  149.                      DestroyWindow( hGrabWnd );
  150.                      DestroyWindow( hWnd );
  151.                      break ;
  152.                   case IDM_ABOUT:       /* show about box */
  153.                      MessageBox( hWnd, 
  154. "SnapW32 - Windows 95 screen capture to clipboard.\nThe Waite Group 1994.",
  155.                      "SnapW32 About", MB_OK );
  156.                      break ;
  157.                   case IDM_HELP:
  158.                      MessageBox ( hWnd, "After clicking the Start Capture\
  159. menu item, move the mouse to the upper left of\
  160. the area you want to copy to the clipboard.\
  161. Hold down the left mouse button while you drag the\
  162. mouse to the lower right of the area.  Once you\
  163. release the mouse button, the area is sent to the\
  164. clipboard and shown in SnapW32's window.",
  165.                     "SnapW32 Help", MB_OK );
  166.                      break;
  167.                }
  168.                break;
  169.  
  170.  
  171.        case WM_PAINT:
  172.             {
  173.                /* display contents of clipboard if bitmap */
  174.                HDC         hDC, hMemDC;
  175.                BITMAP      bm;
  176.                HBITMAP     hBitmap;
  177.                PAINTSTRUCT ps;
  178.                hDC = BeginPaint( hWnd, &ps );
  179.                OpenClipboard( hWnd );
  180.                if ((hBitmap = GetClipboardData( CF_BITMAP ))!=0)
  181.                {
  182.                   // Display CF_BITMAP contents of clipboard in client area.
  183.                   HBITMAP hOldBitmap;
  184.                   hMemDC = CreateCompatibleDC( hDC );
  185.                   hOldBitmap = SelectObject( hMemDC, hBitmap );
  186.                   GetObject( hBitmap, sizeof (BITMAP), (LPSTR) &bm );
  187.                   SetStretchBltMode( hDC, COLORONCOLOR );
  188.                   StretchBlt( hDC, 0, 0, xSize, ySize, hMemDC, 0, 0,
  189.                               bm.bmWidth, bm.bmHeight, SRCCOPY );
  190.                   SelectObject( hDC, hOldBitmap );
  191.                   DeleteDC( hMemDC );
  192.                }
  193.                CloseClipboard( );
  194.                EndPaint( hWnd, &ps );
  195.                break;
  196.             }
  197.        case WM_DESTROY:
  198.                PostQuitMessage(0);
  199.        break;
  200.  
  201.        default:
  202.                return DefWindowProc (hWnd, uMsg, wParam, lParam) ;
  203.    }
  204.    return( 0L );
  205. }
  206.  
  207.  
  208. //
  209. //  This is the window that is displayed while the user captures the screen
  210. // image. It is a transparent window so that the data beneath can be seen.
  211. //
  212. //
  213.  
  214. LRESULT CALLBACK GrabProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  215. {
  216.     HDC             hDC, hMemDC ;
  217.     BITMAP          bm ;
  218.     HBITMAP         hBitmap ;
  219.     PAINTSTRUCT     ps ;
  220.  
  221.     switch (uMsg)   /* process Windows messages */
  222.     {
  223.         case WM_LBUTTONDOWN:    /* starting capturing screen */
  224.                 if (bCapturing)
  225.                 {
  226.                    bBlocking = TRUE;
  227.                    oldend = beg = MAKEPOINTS( lParam );
  228.                    OutlineBlock( hWnd, beg, oldend );
  229.                    SetCursor( LoadCursor( NULL, IDC_CROSS ) );
  230.                 }
  231.                 break;
  232.  
  233.         case WM_MOUSEMOVE:  /* show area as rectangle on screen */
  234.                 if (bBlocking)
  235.                 {
  236.                    end = MAKEPOINTS( lParam );
  237.                    OutlineBlock( hWnd, beg, oldend );  /* erase outline */
  238.                    OutlineBlock( hWnd, beg, end ); /* draw new one */
  239.                    oldend = end;
  240.                 }
  241.                 break;
  242.  
  243.         case WM_LBUTTONUP:      /* capture and send to clipboard */
  244.                 if (bBlocking)
  245.                 {
  246.                    bBlocking = bCapturing = FALSE ;
  247.                    SetCursor( LoadCursor( NULL, IDC_ARROW ) );
  248.                    ReleaseCapture( );     /* free mouse */
  249.                    end = MAKEPOINTS( lParam );
  250.                    OutlineBlock( hWnd, beg, oldend );
  251.                    xSize = abs( beg.x - end.x );
  252.                    ySize = abs( beg.y - end.y );
  253.                    hDC = GetDC( hWnd );
  254.                    hMemDC = CreateCompatibleDC( hDC );
  255.                    hBitmap = CreateCompatibleBitmap( hDC, xSize, ySize );
  256.                    if (hBitmap)
  257.                    {
  258.                       SelectObject( hMemDC, hBitmap );
  259.                       StretchBlt( hMemDC, 0, 0, xSize, ySize,
  260.                                   hDC, beg.x, beg.y, end.x - beg.x,
  261.                                   end.y - beg.y, SRCCOPY );
  262.                       OpenClipboard( hWnd );
  263.                       EmptyClipboard( ) ;
  264.                       SetClipboardData( CF_BITMAP, hBitmap );
  265.                       CloseClipboard( );
  266.                       InvalidateRect( hWnd, NULL, TRUE );
  267.                    }
  268.                    else
  269.                       MessageBeep( 0 );
  270.  
  271.                    DeleteDC( hMemDC );
  272.                    ReleaseDC( hWnd, hDC );
  273.  
  274.                 }
  275.                 ShowWindow( hGrabWnd, SW_HIDE );
  276.                 ShowWindow( hMainWnd, SW_RESTORE ); /* un-minimize window */
  277.                 break;
  278.  
  279.           case WM_PAINT:
  280.                 ValidateRect( hWnd, NULL );
  281.           break;
  282.  
  283.           default:
  284.                 return DefWindowProc( hWnd, uMsg, wParam, lParam );
  285.     }
  286.     return (0L) ;
  287. }
  288.  
  289. /* OutlineBlock() writes a rectangle on the screen given the two corner */
  290. /* points.  The R2_NOT style is used, so drawing twice on the same location */
  291. /* erases the outline. */
  292.  
  293. void OutlineBlock( HWND hWnd, POINTS beg, POINTS end )
  294. {
  295.    HDC   hDC ;
  296.    POINT ptBeg;
  297.    POINT ptEnd;
  298.  
  299.    /* convert mouse 16 bit POINTS to WIN32 POINT Structure that GDI likes */
  300.  
  301.    ptBeg.x = beg.x;
  302.    ptEnd.x = end.x;
  303.    ptBeg.y = beg.y;
  304.    ptEnd.y = end.y;
  305.  
  306.    hDC = CreateDC( "DISPLAY", NULL, NULL, NULL );
  307.    ClientToScreen( hWnd, &ptBeg );        /* convert to screen units */
  308.    ClientToScreen( hWnd, &ptEnd );
  309.    SetROP2( hDC, R2_NOT );                /* use logical NOT pen */
  310.    MoveToEx( hDC, ptBeg.x, ptBeg.y, NULL );   /* draw rectangle */
  311.    LineTo( hDC, ptEnd.x, ptBeg.y );
  312.    LineTo( hDC, ptEnd.x, ptEnd.y );
  313.    LineTo( hDC, ptBeg.x, ptEnd.y );
  314.    LineTo( hDC, ptBeg.x, ptBeg.y );
  315.    DeleteDC( hDC );
  316. }
  317.